﻿using Deployment.Data.SQL.Connections.UI;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Windows.Controls;
using System.Xml.Serialization;

namespace Deployment.Data.SQL.Connections
{
    public class SQLDatabaseConnection : AbstractSQLConnection
    {
        public SQLDatabaseConnection() :base()
        {
            base._TypeDescription = "SQL Server Database Connection";
        }

        [XmlIgnore]
        public string DatabaseName
        {
            get { return builder.InitialCatalog; }
            set
            {
                if (builder.InitialCatalog != value)
                {
                    builder.InitialCatalog = value;
                    IsInternalDataUpdate = true;
                    Data = builder.ConnectionString;
                    OnPropertyChanged("DatabaseName");
                }
            }
        }

        protected override bool performConnectionAccessChecks(SqlConnection connection, out string message)
        {
            try
            {
                connection.Open();
            }
            catch (SqlException sqlEx)
            {
                //If the database doesn't exist we need to check that the user has DBCREATOR role.
                if (sqlEx.Message.StartsWith("Cannot open database \"" + DatabaseName +"\""))
                {
                    SqlConnectionStringBuilder builder1 = new SqlConnectionStringBuilder(connection.ConnectionString);
                    builder1.Remove("Initial Catalog");
                    connection = new SqlConnection(builder1.ConnectionString);
                    connection.Open();

                    using (SqlCommand cmd = new SqlCommand("SELECT IS_SRVROLEMEMBER('dbcreator')", connection))
                    {
                        int? result = cmd.ExecuteScalar() as int?;
                        bool value = (result != null && result == 1);
                        if (value)
                        {
                            message = "Requested database does not exist, deployment must create database.";
                        }
                        else
                        {
                            message = "Requested database does not exist and the authenticated user is not a member of the 'dbCreator' server role.";
                        }
                        return value;
                    }
                }
                else
                {
                    throw sqlEx;
                }
            }
            using (SqlCommand cmd = new SqlCommand("SELECT IS_ROLEMEMBER('db_owner')", connection))
            {
                int? result = cmd.ExecuteScalar() as int?;
                
                bool value = (result != null && result == 1);
                message = value ? null : "Authenticated user must be a member of the 'db_owner' database role.";
                return value;
            }
        }

        protected override UserControl createControl()
        {
            return new SQLDatabaseControl();
        }

        protected override void subClassOnDataUpdated()
        {
            OnPropertyChanged("DatabaseName");
        }

        protected override bool DataValid()
        {
            return !string.IsNullOrEmpty(DatabaseName);
        }
    }
}
